安裝 Terraform 環境
安裝 Terraform
- Terraform 官方網站安裝教學
- 確認已經成功安裝 terraform,在終端機輸入指令
terraform -help
Usage: terraform [global options] <subcommand> [args]
The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.
Main commands:
init Prepare your working directory for other commands
validate Check whether the configuration is valid
plan Show changes required by the current configuration
apply Create or update infrastructure
destroy Destroy previously-created infrastructure
All other commands:
console Try Terraform expressions at an interactive command prompt
fmt Reformat your configuration in the standard style
force-unlock Release a stuck lock on the current workspace
get Install or upgrade remote Terraform modules
graph Generate a Graphviz graph of the steps in an operation
import Associate existing infrastructure with a Terraform resource
login Obtain and save credentials for a remote host
logout Remove locally-stored credentials for a remote host
metadata Metadata related commands
output Show output values from your root module
providers Show the providers required for this configuration
refresh Update the state to match remote systems
show Show the current state or a saved plan
state Advanced state management
taint Mark a resource instance as not fully functional
test Execute integration tests for Terraform modules
untaint Remove the 'tainted' state from a resource instance
version Show the current Terraform version
workspace Workspace management
Global options (use these before the subcommand, if any):
-chdir=DIR Switch to a different working directory before executing the
given subcommand.
-help Show this help output, or the help for a specified subcommand.
-version An alias for the "version" subcommand.
其他需準備環境
自動補齊指令
啟用終端機上的 Tab 自動補齊指令功能
touch ~/.bashrc
touch ~/.zshrc
terraform -install-autocomplete
快速入門教學
- 安裝 docker 應用程式
- mkdir learn-terraform-docker-container
- 建立資料夾放置 Terraform 檔案
- cd learn-terraform-docker-container
- 進入到該資料夾
在資料夾創建 main.tf 檔案並附加以下內容
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
provider "docker" {
host = "npipe:////.//pipe//docker_engine"
}
resource "docker_image" "nginx" {
name = "nginx"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = "tutorial"
ports {
internal = 80
external = 8000
}
}
terraform apply
Initializing the backend...
Initializing provider plugins...
- Finding kreuzwerker/docker versions matching "~> 3.0.1"...
- Installing kreuzwerker/docker v3.0.2...
- Installed kreuzwerker/docker v3.0.2 (self-signed, key ID BD080C4571C6104C)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
derek@liuyuanengdeMBP learn-terraform-docker-container % terraform apply
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# docker_container.nginx will be created
+ resource "docker_container" "nginx" {
+ attach = false
+ bridge = (known after apply)
+ command = (known after apply)
+ container_logs = (known after apply)
+ container_read_refresh_timeout_milliseconds = 15000
+ entrypoint = (known after apply)
+ env = (known after apply)
+ exit_code = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ image = (known after apply)
+ init = (known after apply)
+ ipc_mode = (known after apply)
+ log_driver = (known after apply)
+ logs = false
+ must_run = true
+ name = "tutorial"
+ network_data = (known after apply)
+ read_only = false
+ remove_volumes = true
+ restart = "no"
+ rm = false
+ runtime = (known after apply)
+ security_opts = (known after apply)
+ shm_size = (known after apply)
+ start = true
+ stdin_open = false
+ stop_signal = (known after apply)
+ stop_timeout = (known after apply)
+ tty = false
+ wait = false
+ wait_timeout = 60
+ ports {
+ external = 8000
+ internal = 80
+ ip = "0.0.0.0"
+ protocol = "tcp"
}
}
# docker_image.nginx will be created
+ resource "docker_image" "nginx" {
+ id = (known after apply)
+ image_id = (known after apply)
+ keep_locally = false
+ name = "nginx"
+ repo_digest = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
docker_image.nginx: Creating...
docker_image.nginx: Still creating... [10s elapsed]
docker_image.nginx: Still creating... [20s elapsed]
docker_image.nginx: Creation complete after 22s [id=sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx]
docker_container.nginx: Creating...
docker_container.nginx: Creation complete after 4s [id=09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
在原本的資料夾產生 terraform.tfstate 狀態檔
{
"version": 4,
"terraform_version": "1.6.6",
"serial": 3,
"lineage": "45c004aa-6b2c-aab9-4986-7d580e85c33f",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "docker_container",
"name": "nginx",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 2,
"attributes": {
"attach": false,
"bridge": "",
"capabilities": [],
"cgroupns_mode": null,
"command": [
"nginx",
"-g",
"daemon off;"
],
"container_logs": null,
"container_read_refresh_timeout_milliseconds": 15000,
"cpu_set": "",
"cpu_shares": 0,
"destroy_grace_seconds": null,
"devices": [],
"dns": null,
"dns_opts": null,
"dns_search": null,
"domainname": "",
"entrypoint": [
"/docker-entrypoint.sh"
],
"env": [],
"exit_code": null,
"gpus": null,
"group_add": null,
"healthcheck": null,
"host": [],
"hostname": "09cdec48c9ce",
"id": "09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e",
"image": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9",
"init": false,
"ipc_mode": "private",
"labels": [],
"log_driver": "json-file",
"log_opts": null,
"logs": false,
"max_retry_count": 0,
"memory": 0,
"memory_swap": 0,
"mounts": [],
"must_run": true,
"name": "tutorial",
"network_data": [
{
"gateway": "172.17.0.1",
"global_ipv6_address": "",
"global_ipv6_prefix_length": 0,
"ip_address": "172.17.0.2",
"ip_prefix_length": 16,
"ipv6_gateway": "",
"mac_address": "02:42:ac:11:00:02",
"network_name": "bridge"
}
],
"network_mode": "default",
"networks_advanced": [],
"pid_mode": "",
"ports": [
{
"external": 8000,
"internal": 80,
"ip": "0.0.0.0",
"protocol": "tcp"
}
],
"privileged": false,
"publish_all_ports": false,
"read_only": false,
"remove_volumes": true,
"restart": "no",
"rm": false,
"runtime": "runc",
"security_opts": [],
"shm_size": 64,
"start": true,
"stdin_open": false,
"stop_signal": "SIGQUIT",
"stop_timeout": 0,
"storage_opts": null,
"sysctls": null,
"tmpfs": null,
"tty": false,
"ulimit": [],
"upload": [],
"user": "",
"userns_mode": "",
"volumes": [],
"wait": false,
"wait_timeout": 60,
"working_dir": ""
},
"sensitive_attributes": [],
"private": "eyJzY2hlbWFfdmVyc2lvbiI6IjIifQ==",
"dependencies": [
"docker_image.nginx"
]
}
]
},
{
"mode": "managed",
"type": "docker_image",
"name": "nginx",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"build": [],
"force_remove": null,
"id": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx",
"image_id": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9",
"keep_locally": false,
"name": "nginx",
"platform": null,
"pull_triggers": null,
"repo_digest": "nginx@sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026",
"triggers": null
},
"sensitive_attributes": [],
"private": "bnVsbA=="
}
]
}
],
"check_results": null
}
docker ps
#查看 docker 狀態
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
09cdec48c9ce d453dd892d93 "/docker-entrypoint.…" 13 minutes ago Up 13 minutes 0.0.0.0:8000->80/tcp tutorial
- 在瀏覽器網址欄輸入 localhost:8000
terraform destroy
docker_image.nginx: Refreshing state... [id=sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx]
docker_container.nginx: Refreshing state... [id=09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# docker_container.nginx will be destroyed
- resource "docker_container" "nginx" {
- attach = false -> null
- command = [
- "nginx",
- "-g",
- "daemon off;",
] -> null
- container_read_refresh_timeout_milliseconds = 15000 -> null
- cpu_shares = 0 -> null
- dns = [] -> null
- dns_opts = [] -> null
- dns_search = [] -> null
- entrypoint = [
- "/docker-entrypoint.sh",
] -> null
- env = [] -> null
- group_add = [] -> null
- hostname = "09cdec48c9ce" -> null
- id = "09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e" -> null
- image = "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9" -> null
- init = false -> null
- ipc_mode = "private" -> null
- log_driver = "json-file" -> null
- log_opts = {} -> null
- logs = false -> null
- max_retry_count = 0 -> null
- memory = 0 -> null
- memory_swap = 0 -> null
- must_run = true -> null
- name = "tutorial" -> null
- network_data = [
- {
- gateway = "172.17.0.1"
- global_ipv6_address = ""
- global_ipv6_prefix_length = 0
- ip_address = "172.17.0.2"
- ip_prefix_length = 16
- ipv6_gateway = ""
- mac_address = "02:42:ac:11:00:02"
- network_name = "bridge"
},
] -> null
- network_mode = "default" -> null
- privileged = false -> null
- publish_all_ports = false -> null
- read_only = false -> null
- remove_volumes = true -> null
- restart = "no" -> null
- rm = false -> null
- runtime = "runc" -> null
- security_opts = [] -> null
- shm_size = 64 -> null
- start = true -> null
- stdin_open = false -> null
- stop_signal = "SIGQUIT" -> null
- stop_timeout = 0 -> null
- storage_opts = {} -> null
- sysctls = {} -> null
- tmpfs = {} -> null
- tty = false -> null
- wait = false -> null
- wait_timeout = 60 -> null
- ports {
- external = 8000 -> null
- internal = 80 -> null
- ip = "0.0.0.0" -> null
- protocol = "tcp" -> null
}
}
# docker_image.nginx will be destroyed
- resource "docker_image" "nginx" {
- id = "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx" -> null
- image_id = "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9" -> null
- keep_locally = false -> null
- name = "nginx" -> null
- repo_digest = "nginx@sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026" -> null
}
Plan: 0 to add, 0 to change, 2 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
docker_container.nginx: Destroying... [id=09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e]
docker_container.nginx: Destruction complete after 0s
docker_image.nginx: Destroying... [id=sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx]
docker_image.nginx: Destruction complete after 0s
執行完會產生 terraform.tfstate.backup 檔案
{
"version": 4,
"terraform_version": "1.6.6",
"serial": 3,
"lineage": "45c004aa-6b2c-aab9-4986-7d580e85c33f",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "docker_container",
"name": "nginx",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 2,
"attributes": {
"attach": false,
"bridge": "",
"capabilities": [],
"cgroupns_mode": null,
"command": [
"nginx",
"-g",
"daemon off;"
],
"container_logs": null,
"container_read_refresh_timeout_milliseconds": 15000,
"cpu_set": "",
"cpu_shares": 0,
"destroy_grace_seconds": null,
"devices": [],
"dns": null,
"dns_opts": null,
"dns_search": null,
"domainname": "",
"entrypoint": [
"/docker-entrypoint.sh"
],
"env": [],
"exit_code": null,
"gpus": null,
"group_add": null,
"healthcheck": null,
"host": [],
"hostname": "09cdec48c9ce",
"id": "09cdec48c9ceb8ada30d02a8e2a8b0a69e546af9187d5befef6ba0088da7623e",
"image": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9",
"init": false,
"ipc_mode": "private",
"labels": [],
"log_driver": "json-file",
"log_opts": null,
"logs": false,
"max_retry_count": 0,
"memory": 0,
"memory_swap": 0,
"mounts": [],
"must_run": true,
"name": "tutorial",
"network_data": [
{
"gateway": "172.17.0.1",
"global_ipv6_address": "",
"global_ipv6_prefix_length": 0,
"ip_address": "172.17.0.2",
"ip_prefix_length": 16,
"ipv6_gateway": "",
"mac_address": "02:42:ac:11:00:02",
"network_name": "bridge"
}
],
"network_mode": "default",
"networks_advanced": [],
"pid_mode": "",
"ports": [
{
"external": 8000,
"internal": 80,
"ip": "0.0.0.0",
"protocol": "tcp"
}
],
"privileged": false,
"publish_all_ports": false,
"read_only": false,
"remove_volumes": true,
"restart": "no",
"rm": false,
"runtime": "runc",
"security_opts": [],
"shm_size": 64,
"start": true,
"stdin_open": false,
"stop_signal": "SIGQUIT",
"stop_timeout": 0,
"storage_opts": null,
"sysctls": null,
"tmpfs": null,
"tty": false,
"ulimit": [],
"upload": [],
"user": "",
"userns_mode": "",
"volumes": [],
"wait": false,
"wait_timeout": 60,
"working_dir": ""
},
"sensitive_attributes": [],
"private": "eyJzY2hlbWFfdmVyc2lvbiI6IjIifQ==",
"dependencies": [
"docker_image.nginx"
]
}
]
},
{
"mode": "managed",
"type": "docker_image",
"name": "nginx",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"build": [],
"force_remove": null,
"id": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9nginx",
"image_id": "sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9",
"keep_locally": false,
"name": "nginx",
"platform": null,
"pull_triggers": null,
"repo_digest": "nginx@sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026",
"triggers": null
},
"sensitive_attributes": [],
"private": "bnVsbA=="
}
]
}
],
"check_results": null
}